//
//  PGNetworkHelper+Synchronously.m
//  AFNetworking
//
//  Created by piggybear on 2017/7/25.
//

#import "PGNetworkHelper+Synchronously.h"
NSString *const ResponseErrorKey = @"com.alamofire.serialization.response.error.response";
@implementation PGNetworkHelper (Synchronously)
+ (NSURLSessionTask *)synchronouslyGET:(NSString *)URL parameters:(id)parameters cache:(BOOL)cache responseCache:(HttpRequestCache)responseCache success:(HttpRequestSuccess)success failure:(HttpRequestFailed)failure {
    [self exceptionLogic];
    NSString *urlString = [NSString string];
    if (parameters) {
        //参数拼接url
        NSString *paramStr = [self dealWithParam:parameters];
        urlString = [NSString stringWithFormat:@"%@?%@",URL,paramStr];
    }else{
        urlString = URL;
    }
    //对URL中的中文进行转码
    NSString *pathStr = [urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:pathStr]];
    request.timeoutInterval = 20;
    dispatch_semaphore_t semappore = dispatch_semaphore_create(0);
    NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (data) {
            //利用iOS自带原生JSON解析data数据 保存为Dictionary
            NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
            success?success(dict):nil;
            dispatch_semaphore_signal(semappore);
        }else{
            NSHTTPURLResponse *httpResponse = error.userInfo[ResponseErrorKey];
            if (httpResponse.statusCode != 0) {
                NSString *ResponseStr = [self showErrorInfoWithStatusCode:httpResponse.statusCode];
                failure?failure(ResponseStr):nil;
            } else {
                NSString *ErrorCode = [self showErrorInfoWithStatusCode:error.code];
                failure?failure(ErrorCode):nil;
            }
            dispatch_semaphore_signal(semappore);
        }
    }];
    [task resume];
    dispatch_semaphore_wait(semappore, DISPATCH_TIME_FOREVER);
    return task;
}

+ (NSURLSessionTask *)synchronouslyPOST:(NSString *)URL parameters:(id)parameters cache:(BOOL)cache responseCache:(HttpRequestCache)responseCache success:(HttpRequestSuccess)success failure:(HttpRequestFailed)failure {
    [self exceptionLogic];
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    NSURLSessionTask *task = [self POST:URL parameters:parameters cache:cache headers:nil responseCache:responseCache success:^(id responseObject) {
        if (success) {
            success(responseObject);
        }
        dispatch_semaphore_signal(semaphore);
    } failure:^(id error) {
        if (failure) {
            failure(error);
        }
        dispatch_semaphore_signal(semaphore);
    }];
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    return task;
}

+ (NSURLSessionTask *)synchronouslyUploadWithURL:(NSString *)URL parameters:(NSDictionary *)parameters images:(NSArray<UIImage *> *)images name:(NSString *)name mimeType:(NSString *)mimeType progress:(HttpProgress)progress success:(HttpRequestSuccess)success failure:(HttpRequestFailed)failure {
    [self exceptionLogic];
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    NSURLSessionTask *task = [self uploadWithURL:URL parameters:parameters images:images name:name mimeType:mimeType progress:progress success:^(id responseObject) {
        if (success) {
            success(responseObject);
        }
        dispatch_semaphore_signal(semaphore);
    } failure:^(id error) {
        if (failure) {
            failure(error);
        }
        dispatch_semaphore_signal(semaphore);
    }];
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    return task;
}

+ (NSURLSessionTask *)synchronouslyDownloadWithURL:(NSString *)URL fileDir:(NSString *)fileDir progress:(HttpProgress)progress success:(void (^)(NSString *))success failure:(HttpRequestFailed)failure {
    [self exceptionLogic];
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
    NSURLSessionTask *task = [self downloadWithURL:URL fileDir:fileDir progress:progress success:^(NSString *filePath) {
        if (success) {
            success(filePath);
        }
        dispatch_semaphore_signal(semaphore);
    } failure:^(id error) {
        if (failure) {
            failure(error);
        }
        dispatch_semaphore_signal(semaphore);
    }];
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    return task;
}

+ (void)exceptionLogic {
    if ([NSThread isMainThread]) {
        if ([self manager].completionQueue == nil || [self manager].completionQueue == dispatch_get_main_queue()) {
            @throw
            [NSException exceptionWithName:NSInvalidArgumentException
                                    reason:@"Can't make a synchronous request on the same queue as the completion handler"
                                  userInfo:nil];
        }
    }
}
#pragma mark -- 拼接参数
+ (NSString *)dealWithParam:(NSDictionary *)param{
    NSArray *allkeys = [param allKeys];
    NSMutableString *result = [NSMutableString string];
    
    for (NSString *key in allkeys) {
        NSString *string = [NSString stringWithFormat:@"%@=%@&", key, param[key]];
        [result appendString:string];
    }
    if (result.length>0) {
        NSString * final = [result substringWithRange:NSMakeRange(0, result.length-1)];
        return final;
    }else{
        return @"";
    }
}

#pragma mark
+ (NSString *)showErrorInfoWithStatusCode:(NSInteger)statusCode{
    
    NSString *message = nil;
    switch (statusCode) {
        case 401: {
        
        }
            break;
            
        case 500: {
            message = @"服务器异常！";
        }
            break;
            
        case -1001: {
            message = @"网络请求超时，请稍后重试！";
        }
            break;
            
        case -1002: {
            message = @"不支持的URL！";
        }
            break;
            
        case -1003: {
            message = @"未能找到指定的服务器！";
        }
            break;
            
        case -1004: {
            message = @"服务器连接失败！";
        }
            break;
            
        case -1005: {
            message = @"连接丢失，请稍后重试！";
        }
            break;
            
        case -1009: {
            message = @"互联网连接似乎是离线！";
        }
            break;
            
        case -1012: {
            message = @"操作无法完成！";
        }
            break;
            
        default: {
            message = @"网络请求发生未知错误，请稍后再试！";
        }
            break;
    }
    return message;
    
}
@end
